# 闭包：在调用完函数后，使变量不被销毁
# 1、函数嵌套
# 2、内部函数使用外部变量
# 3、外部函数返回内部函数

'''
def func(name):
    name = name

    def func_inner(speak):
        speak = speak
        print(name+':'+speak)

    return func_inner


Tom = func('Tom')
Jerry = func('Jerry')
Tom("What's up! Man")
Jerry("Is good day!")
'''


# 内部函数改变外部变量

"""
def func():
    num1 = 10

    def func_inner():
        nonlocal num1
        num1 = 20
    print(num1)
    func_inner()
    print(num1)

func()
"""


# 装饰器：有且只有一个参数，并且是函数类型的闭包函数; 扩展函数功能
"""
def func(fn):
    print('装饰器在模块加载时就执行')

    def func_inner():
        print("请先登录")
        fn()
    return func_inner


@func   # 语法糖写法对已有函数完成装饰操作，等于（comment=func(comment)）
def comment():
    print('发表评论')



comment()
"""

# 计算函数运行时间
"""
import time


def get_time(fn):

    def func_inner():
        start = time.time()
        fn()
        end = time.time()
        rseult = end-start
        print(f'该函数运行{rseult}秒')

    return func_inner


@get_time
def work():
    for i in range(100000):
        print(i)


work()

"""

# 通用装饰器，（*args，*kwargs）；多个装饰器

"""
def make_div(fun):

    def inner(*args, **kwargs):
        return "<div>"+fun()+"<div>"

    return inner


def make_p(fun):

    def inner(*args, **kwargs):
        return "<p>"+fun()+"<p>"

    return inner


@make_div
@make_p
def content():
    return 'body'


print(content())
"""
# make_p装饰content，make_div装饰make_p


# 类装饰器

class Check(object):
    # 类名()执行时调用init方法
    def __init__(self, fun):
        self.__fun = fun

    # 让对象像函数一样可以调用
    def __call__(self, *args, **kwargs):
        print('请登录')
        self.__fun()


@Check  # comment = Check(comment)
def comment():
    print("请评论")


comment()
